package jymsg;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList; 
import java.io.OutputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.DataInputStream;
import java.io.ByteArrayOutputStream;


/**
 *
 * @author daniels
 */
public class YahooPacket {

    public static final short YAHOO_SERVICE_LOGIN     = 0x01;
    public static final short YAHOO_SERVICE_LOGOUT    = 0x02;
    public static final short YAHOO_SERVICE_MESSAGE   = 0x06;
    public static final short YAHOO_SERVICE_PING      = 0x12;
    public static final short YAHOO_SERVICE_HANDSHAKE = 0x4C;
    public static final short YAHOO_SERVICE_AUTHRESP  = 0x54;
    public static final short YAHOO_SERVICE_AUTH      = 0x57;
    public static final short YAHOO_SERVICE_DENYBUDDY = 0x86;


    public static final int YAHOO_STATUS_AVAILABLE  = 0x00;
    public static final int YAHOO_STATUS_BRB        = 0x01;
    public static final int YAHOO_STATUS_BUSY       = 0x02;
    public static final int YAHOO_STATUS_NOTATHOME  = 0x03;
    public static final int YAHOO_STATUS_NOTATDESK  = 0x04;
    public static final int YAHOO_STATUS_NOTINOFFICE= 0x05;
    public static final int YAHOO_STATUS_ONPHONE    = 0x06;
    public static final int YAHOO_STATUS_ONVACATION = 0x07;
    public static final int YAHOO_STATUS_OUTTOLUNCH = 0x08;
    public static final int YAHOO_STATUS_STEPPEDOUT = 0x09;
    public static final int YAHOO_STATUS_INVISIBLE  = 0x0c;
    public static final int YAHOO_STATUS_CUSTOM     = 0x63;

    
    private byte[]          header      = {'Y', 'M', 'S', 'G'};
    private byte[]          version     = {0x00, 0x10, 0x00, 0x00};
    private short           length      = 0;
    private short           service     = 0;
    private int             status      = 0;
    private int             session_id  = 0;
    HashMap<String, String> body        = new HashMap<String, String>();

    private byte[]          separator   = {(byte)0xC0, (byte)0x80};




    public void setService(short service) {
        
        this.service = service;
    }

    public short getService() {

        return this.service;
    }

    public void setStatus(int status) {

        this.status = status;
    }

    public int getStatus() {

        return this.status;
    }

    public void setSessionId(int session_id) {

        this.session_id = session_id;
    }

    public int getSessionId() {

        return this.session_id;
    }

    public String insertBody(String key, String value) {

        return this.body.put(key, value);      
    }

    public String getBody(String key) {

        return this.body.get(key);
    }

    public void writePacket(OutputStream out) throws IOException {

        ByteArrayOutputStream baos  = new ByteArrayOutputStream();
        DataOutputStream dataos = new DataOutputStream(out);
        DataOutputStream bodydataos = new DataOutputStream(baos);

        dataos.write(this.header);
        dataos.write(this.version);

        Iterator it = this.body.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, String> pair = (Map.Entry<String, String>)it.next();
            bodydataos.writeBytes(pair.getKey());
            bodydataos.write(this.separator);
            bodydataos.writeBytes(pair.getValue());
            bodydataos.write(this.separator);
        }
        bodydataos.flush();

        this.length = (short)bodydataos.size();

        dataos.writeShort(this.length);
        dataos.writeShort(this.service);
        dataos.writeInt(this.status);
        dataos.writeInt(this.session_id);
        dataos.write(baos.toByteArray());

        dataos.flush();
        out.flush();
    }

    public void readPacket(InputStream in) throws IOException, BadYahooPacketException {

        DataInputStream datais = new DataInputStream(in);

        StringBuilder symsgbuf = new StringBuilder();
        for (int i=0; i<4; i++) {
            symsgbuf.append((char)datais.readByte());
        }

        if (!symsgbuf.toString().equals(new String(this.header))) {
            throw new BadYahooPacketException();
        }

        byte[] version = new byte[4];
        for (int i=0; i<4; i++) {
            version[i] = datais.readByte();
        }

        this.length = datais.readShort();
        this.service = datais.readShort();
        this.status = datais.readInt();
        this.session_id = datais.readInt();

        if (this.length > 0) {
            StringBuilder sbodybuf = new StringBuilder();
            for (int i=0; i<this.length; i++) {
                sbodybuf.append((char)datais.readByte());
            }

            char[] charrbody = sbodybuf.toString().toCharArray();
            StringBuilder sitembuf = new StringBuilder();
            ArrayList<String> itemsArr = new ArrayList<String>();
            for (int i=0; i<charrbody.length; i++) {
                if (charrbody[i] == (char)this.separator[0] &&
                        (i+1 < charrbody.length && charrbody[i+1] == (char)this.separator[1])) {
                    itemsArr.add(sitembuf.toString());
                    sitembuf.setLength(0);
                    i++;
                } else {
                    sitembuf.append(charrbody[i]);
                }
            }

            Iterator it = itemsArr.iterator();
            while (it.hasNext()) {
                this.body.put((String)it.next(), (String)it.next());
            }
        }
    }

}
